package com.laoli.lab37;

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.*;

/**
 * CompletableFuture示例3-有返回值的异步操作且使用默认线程池
 */
public class CompletableFutureDemo03 {
    /**
     * 主线程的任务
     */
    private static void mainTask() {
        // 每隔1秒一次，连续5次输出信息
        for (int i = 1; i <= 5; i++) {
            try {
                System.out.printf("【主线程】执行任务%d：%s\n", i,
                        LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * main方法
     */
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 主线程执行任务-1
        mainTask();
        // 子线程执行有返回值的异步操作任务，由于有返回值，需要用
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            System.out.printf("\t【子线程】开始耗时任务：%s\n",
                    LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
            try {
                Thread.sleep(8000); // 模拟耗时操作（如数据库查询、网络请求）
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "SubTask is Done";//返回值
        });
        // 当主线程需要结果时
        System.out.printf("\t【主线程】拿到子线程的执行结果(%s)：%s\n",
                future.get(), // 通过 get() 阻塞获取结果，实际开发中应结合"回调处理"（这里还没有使用CompletableFuture的回调处理，这行代码还是用了传统的get阻塞获取结果）
                LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
        //由于上面使用了future.get()获取结果，则下面代码将会主线程执行任务-2会被阻塞，也就是需要等待子线程执行完毕返回结果后才能执行任务-2
        // 主线程执行任务-2
        mainTask();
    }
}
